﻿namespace CYPlayer.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Linq;
    using System.Windows.Controls.Primitives;
    using System.Windows.Input;
    using System.Security.Cryptography;
    using CYPlayer.MyServiceReference;
    using DataClasses;
    using Microsoft.Win32;
    using global::ViewModel;

    public class PlaylistsSongsVM : ViewModelBase
    {
        #region Fields

        private static ObservableCollection<PlaylistVM> _playlists;
        private ObservableCollection<SongVM> _songs = new ObservableCollection<SongVM>();
        private int _selectedsongI;
        private SongVM _selectedSong;
        private PlaylistVM _selectedPlaylist;
        private string _selectedPlaylistName = "Unsaved";

        #endregion

        #region Properties

        public int SelectedSongIndex
        {
            get { return _selectedsongI; }
            set { _selectedsongI = value; }
        }

        public virtual SongVM SelectedSong
        {
            get
            {
                return _selectedSong;
            }

            set
            {
                _selectedSong = value;
                RaisePropertyChanged("SelectedSong");
            }
        }

        public string SelectedPlaylistName
        {
            get
            {
                return _selectedPlaylistName;
            }

            set
            {
                _selectedPlaylistName = value;
                RaisePropertyChanged("SelectedPlaylistName");
            }
        }

        public PlaylistVM SelectedPlaylist
        {
            get
            {
                return _selectedPlaylist;
            }

            set
            {
                _selectedPlaylist = value;
                if (_selectedPlaylist != null)
                {
                    SelectedPlaylistName = _selectedPlaylist.PlaylistName;
                    _songs.Clear();

                    var songs = _selectedPlaylist.Playlist.Songs;

                    foreach (var song in songs)
                    {
                        _songs.Add(new SongVM() { Song = song });
                    }
                }

                RaisePropertyChanged("SelectedPlaylist");
            }
        }

        public ObservableCollection<SongVM> Songs
        {
            get { return _songs; }
        }

        public ObservableCollection<PlaylistVM> Playlists
        {
            get
            {
                if (_playlists == null)
                {
                    _playlists = new ObservableCollection<PlaylistVM>();
                    this.UpdatePlaylists();
                }

                return _playlists;
            }
        }

        #endregion

        #region ICommands

        public ICommand AddSong
        {
            get
            {
                return new RelayCommand(p => AddSongExecute());
            }
        }

        public ICommand DeleteSong 
        { 
            get
            {
                return new RelayCommand(DeleteSongExecute);
            } 
        }

        public ICommand SavePlaylist
        {
            get
            {
                return new RelayCommand(param => SavePlaylistExecute());
            }
        }

        public ICommand DeletePlaylist
        {
            get { return new RelayCommand(param => DeletePlaylistExecute()); }
        }

        public ICommand OpenPopup
        {
            get { return new RelayCommand(OpenPopupExecute); }
        }

        #endregion

        #region Helpers

        protected void UpdatePlaylists()
        {
#if DB_TEST
            if (_playlists == null)
            {
                _playlists = new ObservableCollection<PlaylistVM>();
            }
            var playlists = Playlist.Get();
            foreach (var playlist in playlists)
            {
                _playlists.Add(new PlaylistVM { Playlist = playlist });
            }
#else
            var client = new MyPlayerServiceClient();
            
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                return;
            }

            var playlists = client.GetAllPlaylists();
            foreach (var playlist in playlists)
            {
                _playlists.Add(new PlaylistVM { Playlist = playlist });
            }

            client.Close();
#endif
        }

        protected void FillSongs()
        {
#if DB_TEST
            var songs = SelectedPlaylist.Playlist.GetSongs();
            foreach (var song in songs)
            {
                _songs.Add(new SongVM() { Song = song });
            }
#else
            var client = new MyPlayerServiceClient();
            var songs = client.GetPlSongs(SelectedPlaylist.Playlist.Id);
            foreach (var song in songs)
            {
                _songs.Add(new SongVM() { Song = song });
            }

            client.Close();
#endif
        }

        #endregion

        #region Methods(ICommands)

        private void AddSongExecute()
        {
            var addFiledlg = new OpenFileDialog
            {
                FileName = "Song",
                DefaultExt = ".mp3",
                Filter = "Music files (*.mp3)|*.mp3|Window Media Audio (*.wma)|*.wma"
            };
            
            var result = addFiledlg.ShowDialog();
            if (result != true)
            {
                return;
            }

            var filenms = addFiledlg.FileNames;
            using (var client = new MyPlayerServiceClient())
            {
                foreach (var filenm in filenms)
                {
                    using (var mp3File = TagLib.File.Create(filenm))
                    {
                        var title = CheckUnknow(mp3File.Tag.Title);
                        var album = CheckUnknow(mp3File.Tag.Album);
                        var genre = CheckUnknow(mp3File.Tag.FirstGenre);
                        var performer = CheckUnknow(mp3File.Tag.FirstPerformer);
                        var t = mp3File.Properties.Duration;
                        var duration = new TimeSpan(t.Hours, t.Minutes, t.Seconds);
                        var song = new Song(title, album, genre, performer, Song.ConvertSpan(duration), filenm);

                        // client.SaveSong(song);
                        song.Title = ToUtf8(song.Title);
                        Songs.Add(new SongVM { Song = song });
                    }
                }
            }
        }

        private void CheckNonExistantPlaylist()
        {
            if (Playlists.Count != 0)
            {
                SelectedPlaylist = Playlists[0];
            }
            else
            {
                Playlists.Add(new PlaylistVM(){Playlist = new Playlist(SelectedPlaylistName)});
                SelectedPlaylist = Playlists[0];
            }
        }

        void DeleteSongExecute(object nouse)
        {
            if (SelectedSongIndex < 0)
            {
                return;
            }

            var song = SelectedSong;
#if DB_TEST
            song.Song.Delete();
            _songs.Remove(song);
#else
            var client = new MyPlayerServiceClient();
            client.DeleteSong(song.Song);
            _songs.Remove(song);

            client.Close();
#endif
        }

        void SavePlaylistExecute()
        {
            if (_playlists.FirstOrDefault(pl => pl.PlaylistName == _selectedPlaylistName) == null || Songs.Count == 0)
            {
                return;
            }
            //CheckNonExistantPlaylist();
#if DB_TEST
            var selectedpl = SelectedPlaylist.Playlist;
#else
            var client = new MyPlayerServiceClient();

            var selectedpl = new Playlist(SelectedPlaylistName);
            client.SavePlaylist(selectedpl);
            
            client.Close();
#endif
            //Playlists.Add(new PlaylistVM { Playlist = selectedpl });
            //SelectedPlaylist = _playlists[_playlists.Count - 1];
            foreach (var songViewModel in Songs)
            {
                new PlaylistSong(_selectedPlaylist.Playlist.Id, songViewModel.Song.Id);
            }
        }

        void OpenPopupExecute(object parameter)
        {
            var popup = parameter as Popup;
            if (popup == null)
            {
                return;
            }

            popup.IsOpen = true;
            popup.StaysOpen = false;
        }

        void DeletePlaylistExecute()
        {
#if DB_TEST
            var toDelete = PlaylistSong.GetById(_selectedPlaylist.Playlist.Id, "idplaylist");
            var plToDelete = Playlist.GetById(_selectedPlaylist.Playlist.Id);
            plToDelete[0].Delete();
            if (toDelete.Count() != 0)
            {
                foreach (var playlistSong in toDelete)
                {
                    playlistSong.Delete();
                }
            }
            _playlists.Clear();
            this.UpdatePlaylists();
            
#else
            var client = new MyPlayerServiceClient();
            client.DeletePLSongsBy(_selectedPlaylist.Playlist.Id, "idplaylist");
            Playlists.Remove(SelectedPlaylist);

            client.Close();

#endif
        }

        #endregion
    }
}
